package common.util;

import cn.hutool.json.JSONUtil;
import common.bean.ListNode;
import common.bean.TreeNode;

import java.util.*;

/**
 * @author guichang
 * @date 2020/4/26
 */

@SuppressWarnings("all")
public class MyUtil {

    public static final Random RANDOM = new Random();

    public static void main(String[] args) {
        ListNode head = createNode(1, 2, 3, 4, 5, 6, 8, 9);
        printListNode(head);
    }

    /**
     * 随机生成整数数组
     *
     * @param length 数组的长度
     * @param min    最小值（包含）
     * @param max    最大值（包含）
     * @return 随机整数数组
     */
    public static int[] createRandomArray(int length, int min, int max) {
        max++;
        int[] array = new int[length];
        for (int i = 0; i < length; i++) {
            array[i] = RANDOM.ints(min, max).findFirst().getAsInt();
        }
        MyUtil.print("原始数组：\n" + Arrays.toString(array));
        return array;
    }

    /**
     * 创建固定数组
     */
    public static int[] createArray(int... array) {
        MyUtil.print("原始数组：\n" + Arrays.toString(array));
        return array;
    }

    /**
     * 创建固定链表
     */
    public static ListNode createNode(int... nums) {
        ListNode head = null;
        ListNode prev = null;
        for (int i : nums) {
            ListNode next = new ListNode(i);
            if (head == null) {
                head = next;
            } else {
                prev.next = next;
            }
            prev = next;

        }
        MyUtil.print("原始链表：");
        printListNode(head);
        return head;
    }

    /**
     * 层序遍历创建一棵二叉树
     *
     * @param nums 整数数组
     * @return 二叉树
     */
    public static TreeNode createTreeNode(Integer... nums) {
        // 初始化链表
        LinkedList<Integer> list = new LinkedList<>();
        for (Integer n : nums) {
            list.add(n);
        }
        // 头节点
        TreeNode head = createSingleTreeNode(list.poll());
        // 建TreeNode用
        Deque<TreeNode> queue = new ArrayDeque<>();
        queue.offer(head);
        while (!queue.isEmpty()) {
            TreeNode cur = queue.poll();
            cur.left = createSingleTreeNode(list.poll());
            if (cur.left != null) {
                queue.offer(cur.left);
            }
            cur.right = createSingleTreeNode(list.poll());
            if (cur.right != null) {
                queue.offer(cur.right);
            }
        }
        return head;
    }

    private static TreeNode createSingleTreeNode(Integer value) {
        return value == null ? null : new TreeNode(value);
    }

    /**
     * 交换数组两索引值
     *
     * @param nums 数组
     * @param i    索引i
     * @param j    索引j
     */
    public static void swap(int[] nums, int index1, int index2) {
        int temp = nums[index1];
        nums[index1] = nums[index2];
        nums[index2] = temp;
    }

    /**
     * 打印一维数组
     */
    public static void printInt(int[] array) {
        MyUtil.print(Arrays.toString(array));
    }

    /**
     * 打印二维数组
     */
    public static void printInt(int[][] array) {
        if (array == null) {
            MyUtil.print("null");
            return;
        }
        for (int i = 0; i < array.length; i++) {
            System.out.print(i + "-" + Arrays.toString(array[i]));
            System.out.println();
        }
        System.out.println();
    }

    /**
     * 打印链表
     */
    public static void printListNode(ListNode head) {
        if (head == null) {
            System.out.print("null\n");
            return;
        }
        // 递归
        System.out.print(head.val + "->");
        printListNode(head.next);
    }


    /**
     * 层序遍历打印二叉树，空值用null表示
     *
     * @param head 头节点
     * @return [1, 2, 3, null, null, null, null] 这种样式的返回
     */
    public static void printTreeNode(TreeNode head) {
        if (head == null) {
            return;
        }
        LinkedList<Integer> list = new LinkedList<>();
        // 层序遍历用
        Deque<TreeNode> queue = new ArrayDeque<>();
        queue.offer(head);
        list.offer(head.val); // 提前加入
        while (!queue.isEmpty()) {
            TreeNode cur = queue.poll();
            // 仅加入左右节点
            if (cur.left != null) {
                queue.offer(cur.left);
                list.offer(cur.left.val);
            } else {
                list.offer(null);
            }
            if (cur.right != null) {
                queue.offer(cur.right);
                list.offer(cur.right.val);
            } else {
                list.offer(null);
            }
        }
        MyUtil.print(list);
    }


    /**
     * 占位打印
     *
     * @param content 输出内容，占位符用大括号{}
     * @param objs    要替换的值
     */
    public static void printf(String content, Object... objs) {
        String newContent = content;
        for (Object obj : objs) {
            newContent = newContent.replaceFirst("\\{\\}", String.valueOf(obj));
        }
        MyUtil.print(newContent);
    }

    public static void print(Object o) {
        System.out.println(o);
    }

    public static void printJson(Object o) {
        MyUtil.print(JSONUtil.toJsonStr(o));
    }


}